package ru.stepuk.modern.nodes.servers;

import javax.swing.JDialog;
import ru.stepuk.modern.InvalidModelException;
import ru.stepuk.modern.Model;
import ru.stepuk.modern.Request;
import ru.stepuk.modern.nodes.Node;
import ru.stepuk.modern.Timeline;
import ru.stepuk.modern.distributions.Distribution;
import ru.stepuk.modern.gui.SetDistributionDialog;
import ru.stepuk.modern.nodes.DistributionDependent;
import ru.stepuk.modern.nodes.buffers.Buffer;

/**
 *
 * @author ivan
 */
public abstract class Server extends Node implements DistributionDependent {

    protected Timeline timeline;
    protected Distribution distribution;
    protected boolean idle = true;
    protected Buffer buffer = null;
    protected Request currentRequest;
    protected Node next;

    public Server(Model model, Timeline timeline, Distribution distribution) {
        super(model);
        this.timeline = timeline;
        this.distribution = distribution;
    }

    public Distribution getDistribution() {
        return distribution;
    }

    public void setDistribution(Distribution distribution) {
        this.distribution = distribution;
    }

    public boolean isIdle() {
        return idle;
    }

    public JDialog getPropertiesDialog() {
        return new SetDistributionDialog(this, false);
    }

    public void validate() throws InvalidModelException {
        idle = true;
        buffer = null;
        currentRequest = null;

        if (model.getPreviousNodes(this).size() != 1) {
            throw new InvalidModelException(this.name + ": no\\Multiple income to server");
        } else {
            try {
                buffer = (Buffer) model.getPreviousNodes(this).toArray()[0];
            } catch (ClassCastException ex) {
                // No associated buffer
            }
        }

        if (model.getNextNodes(this).size() != 1) {
            throw new InvalidModelException(this.name + ": Not single out\\no out from server");
        } else {
            next = model.getNextNodes(this).toArray(new Node[0])[0];
        }
    }

    public Request getCurrentRequest() {
        return currentRequest;
    }

    public void releaseRequest() {
        //System.out.println(timeline.now() + ": source released " + name);
        next.processRequest(currentRequest);
        currentRequest = null;
        idle = true;
        if ((buffer != null) && (!buffer.isEmpty())) {
            //System.out.println("Fetching...");
            processRequest(buffer.fetchRequest());
        } 
    }
}
